{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 张量的基本计算\n",
   "id": "6fb67eb6b9b78125"
  },
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-03-07T12:26:38.215510Z",
     "start_time": "2025-03-07T12:26:37.054688Z"
    }
   },
   "source": [
    "import torch\n",
    "import numpy as np"
   ],
   "outputs": [],
   "execution_count": 1
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "# 创建张量",
   "id": "45aa86b932126377"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-07T12:32:33.561581Z",
     "start_time": "2025-03-07T12:32:33.558177Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 使用Torch创建张量\n",
    "tensor_1 = torch.tensor([1, 2, 3, 4, 5, 6])\n",
    "print(tensor_1)\n",
    "# 也可使用numpy创建张量,但是numpy转化为tensor后，tensor的类型为float32\n",
    "numpy_array_1 = np.array([1, 2, 3, 4, 5, 6])\n",
    "tensor_2 = torch.Tensor(numpy_array_1)\n",
    "print(tensor_2)\n",
    "print(type(tensor_2).shape)\n",
    "# 也可以使用reshape方法创建张量,这样就可指定张量的形状，Torch.tensor()只能创建一维张量\n",
    "numpy_array_2 = numpy_array_1.reshape(2, 3)\n",
    "tensor_3 = torch.Tensor(numpy_array_2)\n",
    "print(tensor_3)\n",
    "print(type(tensor_3).shape)\n",
    "# 切片操作\n",
    "print(tensor_3[0:2,1])  "
   ],
   "id": "1643c2e47268e318",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([1, 2, 3, 4, 5, 6])\n",
      "tensor([1., 2., 3., 4., 5., 6.])\n",
      "<attribute 'shape' of 'torch._C.TensorBase' objects>\n",
      "tensor([[1., 2., 3.],\n",
      "        [4., 5., 6.]])\n",
      "<attribute 'shape' of 'torch._C.TensorBase' objects>\n",
      "tensor([2., 5.])\n"
     ]
    }
   ],
   "execution_count": 17
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-07T12:33:13.953755Z",
     "start_time": "2025-03-07T12:33:13.950166Z"
    }
   },
   "cell_type": "code",
   "source": [
    "print(torch.empty(3,4))\n",
    "print(torch.ones([3,4]))\n",
    "print(torch.zeros([3,4]))\n",
    "print(torch.rand([3,4]))"
   ],
   "id": "87b52d1297851e83",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[0.0000, 1.8750, 0.0000, 2.0000],\n",
      "        [0.0000, 2.1250, 0.0000, 2.2500],\n",
      "        [0.0000, 2.3125, 0.0000, 2.3750]])\n",
      "tensor([[1., 1., 1., 1.],\n",
      "        [1., 1., 1., 1.],\n",
      "        [1., 1., 1., 1.]])\n",
      "tensor([[0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0.],\n",
      "        [0., 0., 0., 0.]])\n",
      "tensor([[0.3876, 0.5763, 0.4695, 0.5953],\n",
      "        [0.9681, 0.8249, 0.3074, 0.8582],\n",
      "        [0.2841, 0.7688, 0.6216, 0.4740]])\n"
     ]
    }
   ],
   "execution_count": 20
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "",
   "id": "5c8a1a6bb616b8e2"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "#张量的方法和属性",
   "id": "30042111da0f0a91"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-07T12:37:37.390220Z",
     "start_time": "2025-03-07T12:37:37.386654Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 当tensor中只有一个元素时，可以使用item()方法获取该元素的值\n",
    "a = torch.tensor(np.array(2))   # np.array(2):\n",
    "print(np.array(2))\n",
    "print(a)\n",
    "print(a.item()) # item()方法只能用于只有一个元素的张量,不可用于多个元素的张量\n",
    "print(tensor_3)\n",
    "print(tensor_3.shape)   # 输出张量的形状\n",
    "print(tensor_3.size())\n",
    "# size(0)表示第一维的长度\n",
    "print(tensor_3.size(0))\n",
    "# size(1)表示第二维的长度\n",
    "print(tensor_3.size(1))  "
   ],
   "id": "8e5b0ccf81c096e6",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "tensor(2)\n",
      "2\n",
      "tensor([[1., 2., 3.],\n",
      "        [4., 5., 6.]])\n",
      "torch.Size([2, 3])\n",
      "torch.Size([2, 3])\n",
      "2\n",
      "3\n"
     ]
    }
   ],
   "execution_count": 42
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-07T12:38:11.615224Z",
     "start_time": "2025-03-07T12:38:11.613129Z"
    }
   },
   "cell_type": "code",
   "source": [
    "array1 = np.array([[1,2,3],[4,5,6]])\n",
    "print(id(array1))\n",
    "array2=array1.reshape(3,2)\n",
    "print(id(array2))"
   ],
   "id": "221e14ba69baebda",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1969769281552\n",
      "1969805667344\n"
     ]
    }
   ],
   "execution_count": 43
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-07T12:40:54.388619Z",
     "start_time": "2025-03-07T12:40:54.384941Z"
    }
   },
   "cell_type": "code",
   "source": [
    "array2[0,0]=100\n",
    "print(array1)\n",
    "print(array2)\n",
    "# 之所以会这样，是因为reshape()方法只是创建一个新的数组，并不会改变原数组的值，相当于浅拷贝，只拷贝了一层引用。所以当我们修改array2[0,0]时，array1[0,0]也会发生变化。\n",
    "array1.ndim #获取维数"
   ],
   "id": "bbf1e2921c1fdb33",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[[100   2   3]\n",
      " [  4   5   6]]\n",
      "[[100   2]\n",
      " [  3   4]\n",
      " [  5   6]]\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "2"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 45
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-07T12:44:52.300635Z",
     "start_time": "2025-03-07T12:44:52.296276Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 形状改变还可以用view()方法\n",
    "tensor_4 = torch.tensor([[1,2,3],[4,5,6]])\n",
    "tensor_5 = tensor_4.view(6,1)   # 改变形状为(6,1)\n",
    "tensor_6 = tensor_5.view(1,6)   # 改变形状为(1,6)\n",
    "tensor_7 = tensor_6.view(6) # 展开为一维张量\n",
    "print(tensor_4)\n",
    "print(tensor_5)\n",
    "print(tensor_6)\n",
    "print(tensor_7)\n",
    "print(tensor_4.view([6]))\n",
    "print(tensor_4.view(6))\n",
    "print(tensor_4.view(3,-1))  # -1表示由其他维度推断\n",
    "# 判断两个张量是否共享内存\n",
    "tensor_4.untyped_storage().untyped().data_ptr() == tensor_5.untyped_storage().untyped().data_ptr() #判断两个tensor是否共享内存\n"
   ],
   "id": "35629d66729392c6",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[1, 2, 3],\n",
      "        [4, 5, 6]])\n",
      "tensor([[1],\n",
      "        [2],\n",
      "        [3],\n",
      "        [4],\n",
      "        [5],\n",
      "        [6]])\n",
      "tensor([[1, 2, 3, 4, 5, 6]])\n",
      "tensor([1, 2, 3, 4, 5, 6])\n",
      "tensor([1, 2, 3, 4, 5, 6])\n",
      "tensor([1, 2, 3, 4, 5, 6])\n",
      "tensor([[1, 2],\n",
      "        [3, 4],\n",
      "        [5, 6]])\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 62
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-07T12:46:27.557259Z",
     "start_time": "2025-03-07T12:46:27.554080Z"
    }
   },
   "cell_type": "code",
   "source": [
    "#5.转置\n",
    "t3 = torch.tensor([[1,3,4], [2,4,6]])\n",
    "print(t3)\n",
    "print(t3.t()) #转置\n"
   ],
   "id": "10248cb859e662a2",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[1, 3, 4],\n",
      "        [2, 4, 6]])\n",
      "tensor([[1, 2],\n",
      "        [3, 4],\n",
      "        [4, 6]])\n"
     ]
    }
   ],
   "execution_count": 64
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-07T12:46:40.382063Z",
     "start_time": "2025-03-07T12:46:40.378208Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 交换轴,这里的permute和rollaxis功能类型\n",
    "t4 = torch.tensor(np.arange(24).reshape(2,3,4))\n",
    "print(t4.shape)\n",
    "print(\"-\"*50)\n",
    "print(t4.transpose(0,1).shape)#交换0轴和1轴\n",
    "print(\"-\"*50)\n",
    "print(t4.permute(1, 0, 2).shape)#交换0轴和1轴,功能同上\n",
    "print(\"-\"*50)\n",
    "print(t4.permute(1, 2, 0).shape)#变为了3*4*2\n",
    "print(\"-\"*50)\n",
    "print(t4.permute(2, 1, 0).shape)#变为了4*3*2\n",
    "t4.dtype"
   ],
   "id": "be02bd0d7c0c722",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "torch.Size([2, 3, 4])\n",
      "--------------------------------------------------\n",
      "torch.Size([3, 2, 4])\n",
      "--------------------------------------------------\n",
      "torch.Size([3, 2, 4])\n",
      "--------------------------------------------------\n",
      "torch.Size([3, 4, 2])\n",
      "--------------------------------------------------\n",
      "torch.Size([4, 3, 2])\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "torch.int64"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 66
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-07T12:47:18.468037Z",
     "start_time": "2025-03-07T12:47:18.464462Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 在方法后加_，会原地修改\n",
    "x = torch.tensor(np.arange(12).reshape(3,4),dtype = torch.int16)\n",
    "print(x)\n",
    "y= torch.ones([3,4], dtype = torch.int32)\n",
    "print(y)\n",
    "\n",
    "print('-'*50)\n",
    "x.sub_(y) # add_就地修改，不加下划线的会创建一个新的tensor来存储\n",
    "print(x)"
   ],
   "id": "2322280576dbe64d",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[ 0,  1,  2,  3],\n",
      "        [ 4,  5,  6,  7],\n",
      "        [ 8,  9, 10, 11]], dtype=torch.int16)\n",
      "tensor([[1, 1, 1, 1],\n",
      "        [1, 1, 1, 1],\n",
      "        [1, 1, 1, 1]], dtype=torch.int32)\n",
      "--------------------------------------------------\n",
      "tensor([[-1,  0,  1,  2],\n",
      "        [ 3,  4,  5,  6],\n",
      "        [ 7,  8,  9, 10]], dtype=torch.int16)\n"
     ]
    }
   ],
   "execution_count": 69
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-07T12:47:51.743281Z",
     "start_time": "2025-03-07T12:47:51.739923Z"
    }
   },
   "cell_type": "code",
   "source": [
    "#tensor取值,和np完全相同\n",
    "t5 = torch.tensor(np.arange(12).reshape(3,4))\n",
    "print(t5)\n",
    "print(t5[1,2]) #取值\n",
    "print(t5[1]) #取一行\n",
    "print(t5[:,1]) #取一列\n",
    "print(t5[1:3,1:3]) #取一部分\n",
    "print(t5[1:3,:]) #取一部分\n",
    "\n"
   ],
   "id": "3dc553a7ae11e7c2",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[ 0,  1,  2,  3],\n",
      "        [ 4,  5,  6,  7],\n",
      "        [ 8,  9, 10, 11]])\n",
      "tensor(6)\n",
      "tensor([4, 5, 6, 7])\n",
      "tensor([1, 5, 9])\n",
      "tensor([[ 5,  6],\n",
      "        [ 9, 10]])\n",
      "tensor([[ 4,  5,  6,  7],\n",
      "        [ 8,  9, 10, 11]])\n"
     ]
    }
   ],
   "execution_count": 71
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-07T12:48:07.635105Z",
     "start_time": "2025-03-07T12:48:07.630892Z"
    }
   },
   "cell_type": "code",
   "source": [
    "#两个16行，1列的张量相减，求均值\n",
    "t6 = torch.tensor(np.arange(16).reshape(16,1),dtype=torch.float32)\n",
    "t7 = torch.tensor(np.arange(16,32).reshape(16,1),dtype=torch.float32)\n",
    "print(t6)\n",
    "print(t7)\n",
    "((t6-t7)**2).mean()"
   ],
   "id": "507e2ef6e80204d",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[ 0.],\n",
      "        [ 1.],\n",
      "        [ 2.],\n",
      "        [ 3.],\n",
      "        [ 4.],\n",
      "        [ 5.],\n",
      "        [ 6.],\n",
      "        [ 7.],\n",
      "        [ 8.],\n",
      "        [ 9.],\n",
      "        [10.],\n",
      "        [11.],\n",
      "        [12.],\n",
      "        [13.],\n",
      "        [14.],\n",
      "        [15.]])\n",
      "tensor([[16.],\n",
      "        [17.],\n",
      "        [18.],\n",
      "        [19.],\n",
      "        [20.],\n",
      "        [21.],\n",
      "        [22.],\n",
      "        [23.],\n",
      "        [24.],\n",
      "        [25.],\n",
      "        [26.],\n",
      "        [27.],\n",
      "        [28.],\n",
      "        [29.],\n",
      "        [30.],\n",
      "        [31.]])\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "tensor(256.)"
      ]
     },
     "execution_count": 72,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 72
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-07T12:49:34.930094Z",
     "start_time": "2025-03-07T12:49:34.925734Z"
    }
   },
   "cell_type": "code",
   "source": [
    "#初始化两个张量，一个3,4，一个3,1,运算与ndarray相同\n",
    "t8 = torch.tensor(np.arange(12).reshape(3,4),dtype=torch.float32)\n",
    "t9 = torch.tensor(np.arange(3).reshape(3,1),dtype=torch.float32)\n",
    "print(t8)\n",
    "print(t9)\n",
    "t8-t9   # 按照0轴进行广播运算"
   ],
   "id": "781397e418ec68f",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[ 0.,  1.,  2.,  3.],\n",
      "        [ 4.,  5.,  6.,  7.],\n",
      "        [ 8.,  9., 10., 11.]])\n",
      "tensor([[0.],\n",
      "        [1.],\n",
      "        [2.]])\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "tensor([[0., 1., 2., 3.],\n",
       "        [3., 4., 5., 6.],\n",
       "        [6., 7., 8., 9.]])"
      ]
     },
     "execution_count": 74,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 74
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-07T12:49:41.889368Z",
     "start_time": "2025-03-07T12:49:41.766896Z"
    }
   },
   "cell_type": "code",
   "source": [
    "\"\"\"\n",
    "GPU中tensor的使用：\n",
    "1.实例化device， torch.device(\"cpu\" or \"cuda:0\"),选cuda:0需要torch.cuda.is_available()==true\n",
    "2.tensor.to(device),把tensor转化为CUDA支持的tensor或者CPU支持的tensor\n",
    "\"\"\"\n",
    "print(torch.cuda.is_available())\n",
    "if torch.cuda.is_available():\n",
    "    device = torch.device(\"cuda\") #cuda device对象\n",
    "    y = torch.ones_like(x, device = device) #创建一个在cuda熵的tensor\n",
    "    x = x.to(device) #把x转为cuda上的tensor\n",
    "    z = x+y\n",
    "    print(z)\n",
    "    print(z.to(\"cpu\", torch.double))\n",
    "\n",
    "# torch.tensor([1.9806], device = \"cuda:0\")\n",
    "device = torch.device(\"cpu\")\n",
    "x.to(device)"
   ],
   "id": "42eb385de8046ca1",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n",
      "tensor([[ 0,  1,  2,  3],\n",
      "        [ 4,  5,  6,  7],\n",
      "        [ 8,  9, 10, 11]], device='cuda:0', dtype=torch.int8)\n",
      "tensor([[ 0.,  1.,  2.,  3.],\n",
      "        [ 4.,  5.,  6.,  7.],\n",
      "        [ 8.,  9., 10., 11.]], dtype=torch.float64)\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "tensor([[-1,  0,  1,  2],\n",
       "        [ 3,  4,  5,  6],\n",
       "        [ 7,  8,  9, 10]], dtype=torch.int8)"
      ]
     },
     "execution_count": 75,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 75
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-07T12:49:54.400125Z",
     "start_time": "2025-03-07T12:49:54.395307Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 张量的运算\n",
    "t8 = torch.tensor(np.arange(12).reshape(3,4),dtype=torch.float32)\n",
    "t9 = torch.tensor(np.arange(12).reshape(3,4),dtype=torch.float32)\n",
    "t8*t9    # 对应元素相乘"
   ],
   "id": "136c89f50dae52a",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[  0.,   1.,   4.,   9.],\n",
       "        [ 16.,  25.,  36.,  49.],\n",
       "        [ 64.,  81., 100., 121.]])"
      ]
     },
     "execution_count": 76,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 76
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-03-07T12:50:04.229273Z",
     "start_time": "2025-03-07T12:50:04.223159Z"
    }
   },
   "cell_type": "code",
   "source": "torch.mm(t8, t9.transpose(0,1)) ",
   "id": "2494d5ff82a79659",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([[ 14.,  38.,  62.],\n",
       "        [ 38., 126., 214.],\n",
       "        [ 62., 214., 366.]])"
      ]
     },
     "execution_count": 77,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 77
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
